package com.liu.webstore.controller;

import com.liu.webstore.annotation.LoginRequired;
import com.liu.webstore.entity.User;
import com.liu.webstore.enums.StatusEnum;
import com.liu.webstore.service.FollowService;
import com.liu.webstore.service.LikeService;
import com.liu.webstore.service.UserService;
import com.liu.webstore.util.HostHolder;
import com.liu.webstore.util.RedisKeyUtil;
import com.liu.webstore.util.WebstoreUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Objects;

/**
 * @Author LiuYumei
 * @Date 2022/7/11 23:05
 */
@Controller
@RequestMapping("/user")
public class UserController {
    private static Logger log = LoggerFactory.getLogger(UserController.class);

    @Value("${webstore.path.upload}")
    private String uploadPath;

    @Value("${webstore.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private UserService userService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private FollowService followService;

    @GetMapping("/getUser/{id}")
    public User getUser(@PathVariable("id") int id) {
        return userService.getUserById(id);
    }

    @LoginRequired
    @GetMapping("/setting")
    public String getSettingPage() {
        return "/site/setting";
    }

    @LoginRequired
    @PostMapping("/upload")
    public String uploadHeader(MultipartFile headPhoto, Model model) {
        if (null == headPhoto) {
            model.addAttribute("errorMsg", "您还没有选择图片！");
            return "/site/setting";
        }
        String filename = headPhoto.getOriginalFilename();
        // 从最后一个.后面截取，获取图片类型
        String suffix = null;
        if (null != filename) {
            suffix = filename.substring(filename.lastIndexOf("."));
            if (suffix.isEmpty()) {
                model.addAttribute("errorMsg", "文件格式不正确！");
                return "/site/setting";
            }
        }
        // 生成随机字符串
        if (null != suffix) {
            filename = WebstoreUtil.getUuid() + suffix;
        }
        // 确定文件存放路径
        File dest = new File(uploadPath + "/" + filename);
        try {
            // 将headPhoto写入文件
            headPhoto.transferTo(dest);
        } catch (IOException e) {
            log.error("上传文件失败！" + e.getMessage());
            throw new RuntimeException("上传文件失败，服务器发生异常！" + e);
        }
        // 更新当前用户的头像路径（web访问路径http://localhost:8888/webstore/user/header/xxx.png）
        User user = hostHolder.getUser();
        String headerUrl = domain + contextPath + "/user/header/" + filename;
        int row = userService.updateHeadPhoto(user.getId(), headerUrl);
        if (row < 1) {
            log.error("更新当前用户头像失败！");
        }
        return "redirect:/home/index";
    }

    @GetMapping("/header/{filename}")
    public void getHeadPhoto(@PathVariable("filename") String filename, HttpServletResponse response) {
        // 服务器存放路径
        filename = uploadPath + "/" + filename;
        // 文件后缀
        String suffix = filename.substring(filename.lastIndexOf("."));
        // 响应图片
        response.setContentType("image/" + suffix);
        try (
                ServletOutputStream os = response.getOutputStream();
                FileInputStream fis = new FileInputStream(filename)
        ) {
            // 建立缓冲区输出字节
            byte[] buffer = new byte[1024];
            int len;
            // 判断len是否等于-1，等于则表示没读到字节，否则读到
            while ((len = fis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } catch (IOException e) {
            log.error("读取头像失败，" + e.getMessage());
        }
    }

    @LoginRequired
    @PostMapping("/updatePwd")
    public String updatePwd(@CookieValue("ticket") String ticket,
                            String oldPwd, String newPwd, String newPwdAgain, Model model) {
        User user = hostHolder.getUser();
        String password = user.getPassword();
        if (!Objects.equals(WebstoreUtil.getMd5(oldPwd + user.getSalt()), password)) {
            model.addAttribute("passwordMsg", "原始密码不正确！");
            return "/site/setting";
        }
        if (Objects.equals(oldPwd, newPwd)) {
            model.addAttribute("newPwdMsg", "新密码与原始密码不能相同！");
            return "/site/setting";
        }
        if (!Objects.equals(newPwd, newPwdAgain)) {
            model.addAttribute("newPwdAgainMsg", "两次密码不一致，请重新输入！");
            return "/site/setting";
        }
        newPwd = WebstoreUtil.getMd5(newPwd + user.getSalt());
        int row = userService.updatePassword(user.getId(), newPwd);
        if (row < 1) {
            throw new RuntimeException("修改密码发生错误！");
        }
        userService.logout(ticket);
        hostHolder.clear();
        return "redirect:/login";
    }

    /**
     * 个人主页
     */
    @GetMapping("/profile/{userId}")
    public String getProfile(@PathVariable("userId") int userId, Model model) {
        User user = userService.getUserById(userId);
        if (Objects.isNull(user)) {
            throw new RuntimeException("该用户不存在！");
        }
        // 用户
        model.addAttribute("user", user);
        // 点赞数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount", likeCount);
        // 关注数量
        long followeeCount = followService.findFolloweeCount(userId, StatusEnum.ENTITY_TYPE_USER.getStatus());
        model.addAttribute("followeeCount", followeeCount);
        // 粉丝数量
        long followerCount = followService.findFollowerCount(StatusEnum.ENTITY_TYPE_USER.getStatus(), userId);
        model.addAttribute("followerCount", followerCount);
        // 是否已关注
        boolean hasFollowed = false;
        if (Objects.nonNull(hostHolder.getUser())) {
            hasFollowed = followService.hasFollowed(hostHolder.getUser().getId(), StatusEnum.ENTITY_TYPE_USER.getStatus(), userId);
        }
        model.addAttribute("hasFollowed", hasFollowed);
        return "/site/profile";
    }
}
